import {memo, useEffect, useMemo, useRef, useState} from 'react'
import {useSelector} from 'react-redux'
import {createPortal} from 'react-dom'
import {
    BiChevronsDown, BiSkipPrevious, BiChevronsUp, BiSkipNext, BiPlayCircle, BiVolumeFull, BiTransferAlt, BiListUl
} from 'react-icons/bi'
import {PlayControllerContainer, Player, RotateImage} from './styled'
import {getSongUrlInfo} from '../../services/music'
import Slider from '../../components/Slider'
import classNames from 'classnames'
import {transformNumberToTime} from "@/utils"
import {throttle} from "../../utils";
import Ly from "./ly";
// import { getAudioFileArrayBuffer } from "@/services/pure"
export default memo(function APlayController() {

    let imgRef = useRef()
    let canvasRef = useRef()
    let canvasCtxRef = useRef()
    let audioRef = useRef() //audioCtx 保证唯一性确保不会组件重新渲染，内存中存在多个ctx
    let acRef = useRef(new AudioContext())
    let source
    let analyser = useRef()
    const current = useSelector((state) => state.player.current)
    const [playerFullscreen, setPlayerFullscreen] = useState(false) //开启播放器最大化！
    const [currentSrc, setCurrentSrc] = useState("")
    const [duration, setDuration] = useState(0)
    const [currentTime, setCurrentTime] = useState(0)
    /**
     * handleGetMusicUrl 获取歌曲播放路径！
     */
    const handleGetMusicUrl = async () => {
        let res = await getSongUrlInfo({id: current.id})
        setCurrentSrc(res.data[0].url)
        acRef.current = undefined
        acRef.current = new AudioContext()
        try {
            source = acRef.current.createMediaElementSource(audioRef.current)
            analyser.current = acRef.current.createAnalyser()
            source.connect(analyser.current)
            analyser.current.connect(acRef.current.destination)
        } catch (e) {
            console.log('音源已经存在！')
        }
    }

    const playClassnames = classNames({
        fullscreen: playerFullscreen,
    })
    const percentChange = p => {
        audioRef.current.currentTime = p / 100 * audioRef.current.duration
    }
    const drawView = () => {
        const bufferLength = analyser.current.frequencyBinCount
        var dataArray = new Uint8Array(bufferLength);
        analyser.current.getByteFrequencyData(dataArray);
        canvasCtxRef.current?.clearRect(0, 0, canvasRef.current?.width, canvasRef.current?.height)
        let x = 0;
        let width = 2;
        let offset = 1
        let barHeight
        let gradient = canvasCtxRef.current.createLinearGradient(0, 0, 0, 200)
        gradient.addColorStop(0, "#fff");
        gradient.addColorStop(1, "#fee");
        let cvsMid = canvasRef.current.height / 2
        for (let i = 0; i < bufferLength; i++) {
            if (x >= window.innerWidth) {
                break
            }
            canvasCtxRef.current.fillStyle = gradient;
            barHeight = dataArray[i]
            canvasCtxRef.current.fillRect(x, cvsMid - barHeight / 4, width, barHeight / 4);
            canvasCtxRef.current.fillRect(x, cvsMid, width, barHeight / 4);
            x += width + offset
        }
    }
    const onTimeupdate = e => {
        setCurrentTime(e.target.currentTime)
        let count = 5
        let timer = setInterval(() => {
            drawView()
            if (count === 0) {
                clearInterval(timer)
                timer = null
                return
            }
            count -= 1

        }, 50);
    }
    const onCanPlayHandler = e => {
        acRef.current.resume().then(() => {
            setDuration(e.target.duration)
            e.target.play()
        })
    }
    const onWindowResize = throttle((e) => {
        canvasRef.current.width = window.innerWidth
        canvasRef.current.height = window.innerHeight / 4
    }, 300)
    const togglePlayState = () => {
        const isPaused = audioRef.current.paused
        if (!isPaused) {
            audioRef.current.pause()
        } else {
            audioRef.current.play()
        }
        console.log(isPaused)
    }
    const LyricsClick = (timing) => {
        audioRef.current.currentTime = timing
    }
    useEffect(() => {
        if (!current.id) return
        handleGetMusicUrl()
        return () => {
        }
    }, [current])
    useEffect(() => {
        canvasRef.current.width = window.innerWidth
        canvasRef.current.height = window.innerHeight / 5
        canvasCtxRef.current = canvasRef.current.getContext("2d")
    }, [])
    useEffect(() => {
        audioRef.current.addEventListener("canplay", onCanPlayHandler)
        audioRef.current.addEventListener("timeupdate", onTimeupdate)
        window.addEventListener("resize", onWindowResize)
        return () => {
            audioRef.current.removeEventListener("canplay", onCanPlayHandler)
            audioRef.current.removeEventListener("timeupdate", onTimeupdate)
            window.removeEventListener("resize", onWindowResize)
        }
    }, [])
    return createPortal(<PlayControllerContainer className={playClassnames}>
        <div className='showPlay'>
            {/*{audioRef.current.paused.toString()}*/}
            <img ref={imgRef} className="cover" src={current?.al?.picUrl}/>
            <canvas ref={canvasRef}></canvas>
            <RotateImage onClick={togglePlayState} className="play-cover" state={audioRef.current?.paused}
                         src={current?.al?.picUrl}/>
            <p className="play-name">{current?.name}</p>
            <Ly timing={currentTime} onLineClick={LyricsClick}/>
        </div>
        <div className="footer-player">
            <Slider className="play-range" percent={currentTime / duration * 100} onChange={percentChange}/>
            <Player>
                <p>{transformNumberToTime(currentTime)}/{transformNumberToTime(duration)}</p>
                <audio crossOrigin='anonymous' preload='true' ref={audioRef} src={currentSrc}></audio>
                <BiSkipPrevious className="controller-icon previous"/>
                <BiPlayCircle className="controller-icon play"/>
                <BiSkipNext className="controller-icon next"/>
                <BiVolumeFull className="controller-icon next"/>
                <BiTransferAlt className="controller-icon transfer"/>
                <BiListUl className="controller-icon playList"/>
                <div onClick={() => setPlayerFullscreen(!playerFullscreen)}>
                    {!playerFullscreen && <BiChevronsUp className="controller-icon playList"/>}
                    {playerFullscreen && <BiChevronsDown className="controller-icon playList"/>}
                </div>
            </Player>
        </div>
    </PlayControllerContainer>, document.body)
})
